package com.xiaoyu.izf.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.google.common.collect.Lists;
import com.xiaoyu.izf.model.*;
import com.xiaoyu.izf.model.page.DataTableBean;
import com.xiaoyu.izf.model.page.ParamListBean;
import com.xiaoyu.izf.repository.CommissionLogDao;
import com.xiaoyu.izf.repository.UserInfoDao;
import com.xiaoyu.izf.repository.VipInfoDao;
import com.xiaoyu.izf.repository.VipOrderDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.*;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Service
public class VipOrderService extends BaseService{

    @Autowired
    private VipOrderDao vipOrderDao;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private ManualVipUpgradeLogService manualVipUpgradeLogService;
    @Autowired
    private CommissionLogDao commissionLogDao;
    @Autowired
    private VipInfoDao vipInfoDao;
    @Autowired
    private UserInfoDao userInfoDao;

    public DataTableBean list(ParamListBean param,UserInfo user){
        PageRequest pageRequest = buildPageRequestSort(param.getPageNo(), param.getPageLength(), "insertTime","insertTime","desc");
//        pageRequest = PageRequest.of(param.getPageNo(), param.getPageLength(),Sort.Direction.DESC,"insertTime");

        //添加查询条件
        Page<VipOrder> page = vipOrderDao.findAll(new Specification<VipOrder>() {
            /**
             * 构建查询条件（Predicate断言对象）
             * @param root entity：UserInfo
             * @param query
             * @param cb 条件构建器
             * @return
             */
            @Override
            public Predicate toPredicate(Root<VipOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = Lists.newArrayList();
                predicates.add(cb.conjunction());
                if (StringUtils.hasLength(param.getParam().get("type"))){
                    predicates.add(
                            cb.equal(root.get("type").as(Integer.class),param.getParam().get("type")));
                }
                if (StringUtils.hasLength(param.getParam().get("orderStatus"))){
                    predicates.add(
                            cb.equal(root.get("orderStatus").as(Integer.class),param.getParam().get("orderStatus")));
                }
                if (StringUtils.hasLength(param.getParam().get("orderId"))){
                    predicates.add(
                            cb.equal(root.get("id").as(String.class),param.getParam().get("orderId")));
                }
                if (StringUtils.hasLength(param.getParam().get("userName"))){
                    predicates.add(cb.equal(root.get("buyUser").get("userName").as(String.class),param.getParam().get("userName")));
                }
                predicates.add(cb.equal(root.get("isTest").as(Integer.class),0));
                String hierarchy = param.getParam().get("hierarchy");
                if (StringUtils.hasLength(hierarchy)){
                    if ("1".equals(hierarchy)){
                        predicates.add(
                                //断言为equals(期待值，实际值)，跟junit的断言类似
                                cb.equal(root.get("pushUid").as(Integer.class),user.getId()));
                    }else if ("2".equals(hierarchy)){
                        predicates.add(cb.equal(root.get("gradePushUid").as(Integer.class),user.getId()));
                    }
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        },pageRequest);
//		Page<UserInfo> page = userInfoDao.findAll(pageRequest);

        DataTableBean data = dataTableBean(page,param);
        List<VipOrder> list = page.getContent();
        List<VipOrder> list2 = new ArrayList<>();
        if(list!=null&&list.size()>0){
            for (VipOrder order:list){
                if(order.getPushUid()>0){
                    UserInfo pushUser = userInfoService.adminUserOne(order.getPushUid());
                    order.setPushUser(pushUser);
                }
                if(order.getGradePushUid()>0){
                    UserInfo pushUser = userInfoService.adminUserOne(order.getGradePushUid());
                    order.setGradeUser(pushUser);
                }
                list2.add(order);
            }
        }
        data.setAaData(list2);
        return data;
    }

    @Transactional
    public VipOrder orderAdd(UserInfo user,int type,int payAmount){
        String orderId = "o"+System.currentTimeMillis() + (long) (Math.random() * 10000000L);
        //用户当前vip等级
        //VipInfo vip = vipInfoDao.findOneById(user.getVipType());
        VipOrder order = new VipOrder();
        order.setId(orderId);
        order.setUid(user.getId());
        order.setVipType(user.getVipType());
        order.setOrderStatus(1);
        order.setOutTradeNo("");
        order.setType(type);
        order.setInsertTime(new Timestamp(System.currentTimeMillis()));
        order.setPayTime(new Timestamp(System.currentTimeMillis()));
        order.setIsTest(user.getIsTest());
        //int payAmount = vip.getVipPrice();
        order.setTotAmount(payAmount);
        //存在上级推广人
        if(user.getPushUid()>0&&user.getIsTest()==0){
            UserInfo pushUser = userInfoDao.findOneById(user.getPushUid());
            if(pushUser.getVipType()>0) {
                //上级推广人vip
                VipInfo vip1 = vipInfoDao.findOneById(pushUser.getVipType());
                int commissioin = payAmount * vip1.getVipSplite() / 100;
                if(user.getVipType()==21||user.getVipType()==23){//推荐的是服务商
                    commissioin = payAmount * vip1.getServerSplite() / 100;
                }
                order.setPushUid(pushUser.getId());
                order.setPushSplit(vip1.getVipSplite());
                order.setPushAmount(commissioin);
                commissionLogAdd(orderId, pushUser, vip1, 1, payAmount, commissioin, user.getId());

                //给上级推广人计算佣金
                pushUser.setCommission(pushUser.getCommission() + commissioin);
                pushUser.setCommissionDeposit(pushUser.getCommissionDeposit() + commissioin);
                userInfoDao.save(pushUser);
            }
        }else{
            order.setPushUid(0);
            order.setPushSplit(0);
            order.setPushAmount(0);
        }
        //存在上上级推广人
        if(user.getGradePushUid()>0&&user.getIsTest()==0){
            UserInfo pushUser = userInfoDao.findOneById(user.getGradePushUid());
            if(pushUser.getVipType()>0) {
                //上上级推广人vip
                VipInfo vip1 = vipInfoDao.findOneById(pushUser.getVipType());
                int commissioin = payAmount * vip1.getVipGradeSplite() / 100;
                if(user.getVipType()==21||user.getVipType()==23){//推荐的是服务商
                    commissioin = payAmount * vip1.getServerGradeSplite() / 100;
                }
                order.setGradePushUid(pushUser.getId());
                order.setGradeSplit(vip1.getVipGradeSplite());
                order.setGradeAmount(commissioin);
                commissionLogAdd(orderId, pushUser, vip1, 2, payAmount, commissioin, user.getId());

                //给上上级推广人计算佣金
                pushUser.setCommission(pushUser.getCommission() + commissioin);
                pushUser.setCommissionDeposit(pushUser.getCommissionDeposit() + commissioin);
                userInfoDao.save(pushUser);
            }
        }else {
            order.setGradePushUid(0);
            order.setGradeSplit(0);
            order.setGradeAmount(0);
        }
        order = vipOrderDao.save(order);

        //如果用户还没有授权码，赋予授权码
        if(StringUtils.isEmpty(user.getOfficialServiceNumber())||"粉丝".equals(user.getOfficialServiceNumber())){
            int n = userInfoService.regUserCount(DateUtil.format(user.getRegTime(),"yyyy-MM"))+1;
            while (true) {
                String osn = DateUtil.format(DateUtil.date(), "yyyyMM") + NumberUtil.decimalFormat("000", n);
                UserInfo userInfo1 = userInfoDao.findByOfficialServiceNumber(osn);
                if(userInfo1==null) {
                    user.setOfficialServiceNumber(osn);
                    break;
                }
                n++;
            }
        }

        user.setToTheAccount(1);
        userInfoDao.save(user);
        return order;
    }

    public void commissionLogAdd(String orderId, UserInfo pushUser, VipInfo vip, int gradeType, int totAmount, int commission, int sourceUid){
        CommissionLog log = new CommissionLog();
        log.setUid(pushUser.getId());
        log.setUserVipType(vip.getId());
        log.setGradeType(gradeType);
        log.setTotalAmount(totAmount);
        log.setOrderId(orderId);
        log.setCommissioin(commission);
        log.setLogType(1);
        log.setLogTime(new Timestamp(System.currentTimeMillis()));
        log.setPayStatus(1);
        log.setSourceUid(sourceUid);
        log.setIsOnline(0);
        commissionLogDao.save(log);
    }

    public VipOrder vipOrder(String orderId){
        return vipOrderDao.findOneById(orderId);
    }
}
